package com.moji.config;

import com.alibaba.fastjson.JSONObject;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.Claim;
import com.moji.util.JwtTokenUtil;
import com.moji.util.ResultCode;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import reactor.core.publisher.Mono;

import javax.annotation.Resource;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Configuration
public class TokenFilter implements Filter {

    private static Logger logger = LoggerFactory.getLogger(TokenFilter.class);


    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private JwtTokenUtil jwtTokenUtil;

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
        //设置编码格式
        httpServletResponse.setCharacterEncoding(StandardCharsets.UTF_8.name());
        //获取请求的url
        String url = httpServletRequest.getRequestURI();
        logger.info("当前登录账号url——获取=================="+url);
        //需要过滤的url
        Set<String> ALLOWED_PATHS = Collections.unmodifiableSet(new HashSet<>(
                Arrays.asList("/swagger-ui.html",
                              "/v2/api-docs",
                              "/doc.html",
                              "/api/login",
                              "/login",
                              "/swagger-resources/configuration/ui",
                              "/api/logout",
                              "/swagger-resources",
                              "/api/ccpBasicInfoCfg/getCcpBasicInfo",
                              "/api/getUserCode",
                        "/mjBanner/queryByPage",
                        "/mjBasicInfo/queryByPage",
                        "/mjProduct",
                        "/mjSolution",
                        "/mjHomeProduct/queryByProductId",
                        "/mjHomeSolution/queryBySolutionId",
                        "/api/MjUploadFiles/picture"

                              )));
        //获取token令牌
        String token = this.resolveToken(httpServletRequest);
        //预加载不校验token
        if ("OPTIONS".equals(httpServletRequest.getMethod())) {
            httpServletResponse.setStatus(HttpServletResponse.SC_OK);
            filterChain.doFilter(httpServletRequest, httpServletResponse);
        } else {
            if (ALLOWED_PATHS.contains(url) || url.contains("js") || url.contains("css") || url.contains("rest")|| url.contains("web")) {
                filterChain.doFilter(servletRequest, servletResponse);
            } else {
                //判断token是否为空
                if (StringUtils.isEmpty(token)) {
                    int code = new Long(ResultCode.TOKEN_IS_NULL.getCode()).intValue();
                    httpServletResponse.sendError(code,ResultCode.TOKEN_IS_NULL.getMsg());
                    return;
                }

                //判断token是否过期
//                if(!redisTemplate.hasKey(token)){
//                    int code = new Long(ResultCode.TOKEN_IS_EXPIRE.getCode()).intValue();
//                    httpServletResponse.sendError(code,ResultCode.TOKEN_IS_EXPIRE.getMsg());
//                    return;
//                } else{
//                    //放入redis缓存
//                    //redisTemplate.opsForValue().set(token,token, Integer.valueOf(CcpEnumConfig.CCP_SYSTEM_TOKEN_TIME.getCode()), TimeUnit.MINUTES);
//                    //redisTemplate.expire(token, Integer.valueOf(CcpEnumConfig.CCP_SYSTEM_TOKEN_TIME.getCode()), TimeUnit.MINUTES);
//                }
                //解析token
                Map<String, Claim> userData = null;
                String userName = "";
                try {
                    userData = jwtTokenUtil.verifyToken(token);
                    userName = userData.get("loginId").asString();
                    Date date = userData.get("exp").asDate();
                    logger.info("token自身过期时间=================="+date);
                } catch (TokenExpiredException tokenExpiredException) {
                    int code = new Long(ResultCode.TOKEN_IS_EXPIRE.getCode()).intValue();
                    httpServletResponse.sendError(code,ResultCode.TOKEN_IS_EXPIRE.getMsg());
                    return;
                } catch (Exception e) {
                    logger.error(e.getMessage());
                    logger.error("token解码异常");
                    //解码异常则抛出异常
                    int code = new Long(ResultCode.TOKEN_IS_ERROR.getCode()).intValue();
                    httpServletResponse.sendError(code,ResultCode.TOKEN_IS_ERROR.getMsg());
                    return;
                }
                logger.info("当前登录账号=================="+userName);
                filterChain.doFilter(servletRequest, servletResponse);
            }
        }
    }

    /**
     * 获取Token
     *
     * @param request /
     * @return /
     */
    private String resolveToken(HttpServletRequest request) {
        return request.getHeader("Authorization");
    }
}
